package com.project.seckill.controller;

import com.google.common.util.concurrent.RateLimiter;
import com.project.seckill.common.ResultBody;
import com.project.seckill.common.exception.MyException;
import com.project.seckill.service.OrderService;
import com.project.seckill.service.ProductService;
import com.project.seckill.utils.RedisUtils;
import com.wf.captcha.SpecCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Slf4j
@Controller
@RequestMapping("order")
public class OrderController {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private ProductService productService;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private OrderService orderService;

    /**
     * 限流器：最多每秒处理1000个请求
     */
    private RateLimiter rateLimiter = RateLimiter.create(1000);

    /**
     * 获取生成验证码方法
     *
     * @param userId
     * @param response
     */
    @RequestMapping(path = "/captcha", method = RequestMethod.GET)
    public void getCaptcha(Integer userId, HttpServletResponse response) {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);
        if (userId == null) {
            throw new MyException("用户不能为空");
        }
        String key = "captcha:" + userId;
        redisUtils.set(key, specCaptcha.text(), 30L);

        response.setContentType("image/png");
        try {
            OutputStream os = response.getOutputStream();
            specCaptcha.out(os);
        } catch (IOException e) {
            log.error("发送验证码失败：" + e.getMessage());
        }
    }

    @ResponseBody
    @RequestMapping("/getToken")
    public ResultBody getToken(String code, Integer userId, Long productId) {
        if (StringUtils.isBlank(code)) {
            throw new MyException("请输入正确的验证码");
        }
        if (userId == null) {
            throw new MyException("用户不存在");
        }
        String key = "captcha:" + userId;
        String realCode = (String) redisUtils.get(key);
        if (StringUtils.isBlank(realCode)) {
            throw new MyException("验证码已过期");
        }
        if (!realCode.equals(code)) {
            throw new MyException("请输入正确的验证码");
        }
        String token = productService.generateToken(userId, productId);
        if (StringUtils.isBlank(token)) {
            throw new MyException("下单失败");
        }
        return ResultBody.success(token);
    }

    @ResponseBody
    @RequestMapping("/createOrder")
    public ResultBody createOrder(Integer userId, Long productId, String token) {
        //获取令牌
        if (!rateLimiter.tryAcquire(1, TimeUnit.MINUTES)) {
            throw new MyException("服务器繁忙");
        }

        String key = "product:token:" + userId + ":" + productId;
        String rToken = (String) redisUtils.get(key);
//        if (StringUtils.isBlank(rToken)){
//            throw new MyException("下单失败");
//        }
        Future future = taskExecutor.submit(new Callable() {

            @Override
            public Object call() throws Exception {
                orderService.createOrderAsync(userId, productId);
                return null;
            }
        });
        try {
            future.get();
        } catch (Exception e) {
            log.info("订单下单失败原因: " + e.getMessage());
            throw new MyException("下单失败");
        }
        return ResultBody.success();
    }
}
